import { Injectable } from '@angular/core';
import { Platform, AlertController, LoadingController, ToastController, Loading } from 'ionic-angular';
import { AppVersion } from '@ionic-native/app-version';
import { File, FileEntry } from "@ionic-native/file";
import { Transfer, TransferObject } from '@ionic-native/transfer';
import { Network } from "@ionic-native/network";
import { Camera, CameraOptions } from "@ionic-native/camera";
import { InAppBrowser } from '@ionic-native/in-app-browser';
import { APP_DOWNLOAD, DOMAIN, APK_DOWNLOAD, REQUEST_TIMEOUT, IMAGE_SIZE, QUALITY_SIZE, FUNDEBUG_API_KEY, CODE_PUSH_DEPLOYMENT_KEY } from "./Config";
import { Http, Response, URLSearchParams } from '@angular/http';
import { ImagePicker } from "@ionic-native/image-picker";
import { FileOpener } from '@ionic-native/file-opener';
import { GlobalData } from "./GlobalData";
import { Observable } from "rxjs";
import { Logger } from "./Logger";

@Injectable()
export class NativeService {

  private loadingIsOpen: boolean = false;
  private loading: Loading;
  private toast;

  constructor(private platform: Platform,
    private alertCtrl: AlertController,
    private transfer: Transfer,
    private appVersion: AppVersion,
    private file: File,
    private http: Http,
    private fo: FileOpener,
    private camera: Camera,
    private globalData: GlobalData,
    private network: Network,
    private loadingCtrl: LoadingController,
    private toastCtrl: ToastController,
    private imagePicker: ImagePicker,
    public logger: Logger,
    private inAppBrowser: InAppBrowser) {
  }

  /**
   * 检查app是否需要升级
   */
  async detectionUpgrade() {
    //这里连接后台获取app最新版本号,然后与当前app版本号(this.getVersionNumber())对比
    //版本号不一样就需要升级,不需要升级就return
    var res = await this.http.get(DOMAIN + "update.json").toPromise()
    var verObj = JSON.parse(res['_body']);
    //取本地版本
    try {
      var appVer = await this.getVersionNumber();
      //alert(appVer + "-- 服务器版本" + verObj['version']);
      if (parseFloat(verObj['version']) > parseFloat(appVer)) {
        this.promatUpdate(verObj.desc);
        return true;
      } else
        return false;

    } catch (error) {
      alert("无法取得app版本号")
    }

  }

  //提示升级 
  promatUpdate = (desc) => {
    this.alertCtrl.create({
      title: '升级',
      subTitle: '发现新版本,是否立即升级？',
      message: desc,
      buttons: [{ text: '取消' },
      {
        text: '确定',
        handler: () => {
          this.downloadApp();
        }
      }
      ]
    }).present();

  }

  /**
   * 下载安装app
   */
  downloadApp = () => {
    if (this.isAndroid()) {
      let alert = this.alertCtrl.create({
        title: '下载进度：0%',
        enableBackdropDismiss: false,
        buttons: ['后台下载']
      });
      alert.present();

      const fileTransfer: TransferObject = this.transfer.create();
      const apk = this.file.externalRootDirectory + 'nail-art.apk'; //apk保存的目录

      fileTransfer.download(APK_DOWNLOAD, apk).then(() => {
        //进行安装
        this.fo.open(apk, 'application/vnd.android.package-archive');
      });

      fileTransfer.onProgress((event: ProgressEvent) => {
        let num = Math.floor(event.loaded / event.total * 100);
        if (num === 100) {
          alert.dismiss();

        } else {
          let title = document.getElementsByClassName('alert-title')[0];
          title && (title.innerHTML = '下载进度：' + num + '%');
        }
      });
    }
    if (this.isIos()) {
      this.openUrlByBrowser(APP_DOWNLOAD);
    }
  }

  /**
   * 通过浏览器打开url
   */
  openUrlByBrowser(url: string): void {
    this.inAppBrowser.create(url, '_system');
  }

  /**
   * 是否真机环境
   * @return {boolean}
   */
  isMobile(): boolean {
    return this.platform.is('mobile') && !this.platform.is('mobileweb');
  }

  /**
   * 是否android真机环境
   * @return {boolean}
   */
  isAndroid(): boolean {
    return this.isMobile() && this.platform.is('android');
  }

  /**
   * 是否ios真机环境
   * @return {boolean}
   */
  isIos(): boolean {
    return this.isMobile() && (this.platform.is('ios') || this.platform.is('ipad') || this.platform.is('iphone'));
  }

  /**
   * 获得app版本号,如0.01
   * @description  对应/config.xml中version的值
   * @returns {Promise<string>}
   */
  getVersionNumber = (): Promise<string> => {
    return new Promise((resolve) => {
      this.appVersion.getVersionNumber().then((value: string) => {
        resolve(value);
      }).catch(err => {
        console.log('getVersionNumber:' + err);
      });
    });
  }



  /**
   * 统一调用此方法显示loading
   * @param content 显示的内容
   */
  showLoading(content: string = ''): void {
    if (!this.globalData.showLoading) {
      return;
    }
    if (!this.loadingIsOpen) {
      this.loadingIsOpen = true;
      this.loading = this.loadingCtrl.create({
        content: content
      });
      this.loading.present();
      setTimeout(() => {
        this.dismissLoading();
      }, REQUEST_TIMEOUT);
    }
  };

  dismissLoading() {
    if (this.loadingIsOpen) {
      this.loadingIsOpen = false;
      this.loading.dismiss();
    }
  }




  /**
   * 通过图库选择多图
   * @param options
   */
  getMultiplePicture(options = {}): Observable<any> {
    let that = this;
    let ops = Object.assign({
      maximumImagesCount: 6,
      width: IMAGE_SIZE,//缩放图像的宽度（像素）
      height: IMAGE_SIZE,//缩放图像的高度（像素）
      quality: QUALITY_SIZE//图像质量，范围为0 - 100
    }, options);

    return Observable.create(observer => {
      this.imagePicker.getPictures(ops).then(files => {
        let destinationType = options['destinationType'] || 0;//0:base64字符串,1:图片url
        if (destinationType === 1) {
          observer.next(files);
        } else {
          let imgBase64s = [];//base64字符串数组
          for (let fileUrl of files) {
            that.convertImgToBase64(fileUrl).subscribe(base64 => {
              imgBase64s.push(base64);
              if (imgBase64s.length === files.length) {
                observer.next(imgBase64s);
              }
            })
          }
        }
      }).catch(err => {
        this.logger.log(err, '通过图库选择多图失败');
        this.alert('获取照片失败');
        observer.error(false);
      });
    });
  };

  /**
       * 统一调用此方法显示提示信息
       * @param message 信息内容
       * @param duration 显示时长
       */
  showToast = (message: string = '操作完成', duration: number = 2500) => {
    this.toast = this.toastCtrl.create({
      message: message,
      duration: duration,
      position: 'top',
      showCloseButton: true,
      closeButtonText: '关闭'
    });
    this.toast.present();
  };

  /**
         * 通过图库获取照片
         * @param options
         * @return {Promise<T>}
         */
  getPictureByPhotoLibrary = (options = {}) => {
    return new Promise((resolve) => {
      this.camera.getPicture(Object.assign({
        sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
      }, options)).then(imageBase64 => {
        resolve(imageBase64);
      }).catch(err => {
        String(err).indexOf('cancel') != -1 ? this.showToast('取消选择图片', 1500) : this.showToast('获取        照片失败');
      });
    });
  };


  /**
   * 关闭loading
   */
  hideLoading(): void {
    if (!this.globalData.showLoading) {
      this.globalData.showLoading = true;
    }
    setTimeout(() => {
      this.dismissLoading();
    }, 200);
  };


  /**
 * 获取网络类型 如`unknown`, `ethernet`, `wifi`, `2g`, `3g`, `4g`, `cellular`, `none`
 */
  getNetworkType(): string {
    if (!this.isMobile()) {
      return 'wifi';
    }
    return this.network.type;
  }



  /**
   * 判断是否有网络
   */
  isConnecting(): boolean {
    return this.getNetworkType() != 'none';
  }



  /**
   * 一个确定按钮的alert弹出框.
   * @type {(title: string, subTitle?: string, message?: string) => void}
   */
  alert = (() => {
    let isExist = false;
    return (title: string, subTitle: string = '', message: string = ''): void => {
      if (!isExist) {
        isExist = true;
        this.alertCtrl.create({
          title: title,
          subTitle: subTitle,
          message: message,
          buttons: [{
            text: '确定', handler: () => {
              isExist = false;
            }
          }],
          enableBackdropDismiss: false
        }).present();
      }
    };
  })();


  /**
   * 根据图片绝对路径转化为base64字符串
   * @param path 绝对路径
   */
  convertImgToBase64(path: string): Observable<string> {
    return Observable.create(observer => {
      this.file.resolveLocalFilesystemUrl(path).then((fileEnter: FileEntry) => {
        fileEnter.file(file => {
          let reader = new FileReader();
          reader.onloadend = function (e) {
            observer.next(this.result);
          };
          reader.readAsDataURL(file);
        });
      }).catch(err => {
        this.logger.log(err, '根据图片绝对路径转化为base64字符串失败');
        observer.error(false);
      });
    });
  }


  /**
   * 使用cordova-plugin-camera获取照片
   * @param options
   */
  getPicture(options: CameraOptions = {}): Observable<string> {
    let ops: CameraOptions = Object.assign({
      sourceType: this.camera.PictureSourceType.CAMERA,//图片来源,CAMERA:拍照,PHOTOLIBRARY:相册
      destinationType: this.camera.DestinationType.DATA_URL,//默认返回base64字符串,DATA_URL:base64   FILE_URI:图片路径
      quality: QUALITY_SIZE,//图像质量，范围为0 - 100
      allowEdit: false,//选择图片前是否允许编辑
      encodingType: this.camera.EncodingType.JPEG,
      targetWidth: IMAGE_SIZE,//缩放图像的宽度（像素）
      targetHeight: IMAGE_SIZE,//缩放图像的高度（像素）
      saveToPhotoAlbum: false,//是否保存到相册
      correctOrientation: true//设置摄像机拍摄的图像是否为正确的方向
    }, options);
    return Observable.create(observer => {
      this.camera.getPicture(ops).then((imgData: string) => {
        if (ops.destinationType === this.camera.DestinationType.DATA_URL) {
          observer.next('data:image/jpg;base64,' + imgData);
        } else {
          observer.next(imgData);
        }
      }).catch(err => {
        if (err == 20) {
          this.alert('没有权限,请在设置中开启权限');
          return;
        }
        if (String(err).indexOf('cancel') != -1) {
          return;
        }
        this.logger.log(err, '使用cordova-plugin-camera获取照片失败');
        this.alert('获取照片失败');
        observer.error(false);
      });
    });
  };


  /**
   * 通过拍照获取照片
   * @param options
   */
  getPictureByCamera(options: CameraOptions = {}): Observable<string> {
    let ops: CameraOptions = Object.assign({
      sourceType: this.camera.PictureSourceType.CAMERA,
      destinationType: this.camera.DestinationType.DATA_URL//DATA_URL: 0 base64字符串, FILE_URI: 1图片路径
    }, options);
    return this.getPicture(ops);
  };


  geCityData() {
    return this.http.get('./assets/data/city-data.json').map((res: Response) => res.json());
  }



}
